package DiffMerge;
import java.io.*;
import java.net.URL;
import javax.swing.JOptionPane;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import javax.xml.stream.events.XMLEvent;
import GUI.InterfacePrincipal;

public class StAx_Merge extends XMLMerge {
	private static final QName prodName= new QName("product");
	private static final QName pidName= new QName("pid");
	private static String textoTextPane = "";
	
	public StAx_Merge() {
		setCaminhoArquivoBase(super.getCaminhoArquivoBase());
		setCaminhoArquivoDerivado(super.getCaminhoArquivoDerivado());
	}
	
	@Override
	public String getCaminhoArquivoBase() {
		// TODO Auto-generated method stub
		return super.getCaminhoArquivoBase();
	}
	
	@Override
	public void setCaminhoArquivoBase(String caminhoArquivoBase) {
		// TODO Auto-generated method stub
		super.setCaminhoArquivoBase(caminhoArquivoBase);
	}
	
	@Override
	public String getCaminhoArquivoDerivado() {
		// TODO Auto-generated method stub
		return super.getCaminhoArquivoDerivado();
	}
	
	@Override
	public void setCaminhoArquivoDerivado(String caminhoArquivoDerivado) {
		// TODO Auto-generated method stub
		super.setCaminhoArquivoDerivado(caminhoArquivoDerivado);
	}
	
	@Override
	protected String getResultadoMergeAutomatico() {
		// TODO Auto-generated method stub
		InterfacePrincipal.txtPane3.setText("");
		return super.getResultadoMergeAutomatico();
	}
	
	public void setExecutarMergeAutomatico() {
		textoTextPane = "";
		
		try{
			setStAx();
			InterfacePrincipal.txtPane3.setText(textoTextPane.substring(0,textoTextPane.length() - 11));
			JOptionPane.showMessageDialog(null,"Mesclagem efetuada com sucesso!");
		}catch(FileNotFoundException e){
			e.printStackTrace();
			JOptionPane.showMessageDialog(null, "Erro ao executar merge automático", "Erro", JOptionPane.ERROR_MESSAGE);
		}catch(XMLStreamException e){
			e.printStackTrace();
			JOptionPane.showMessageDialog(null, "Erro ao executar merge automático", "Erro", JOptionPane.ERROR_MESSAGE);
		}
	}
	
	@Override
	protected String getResultadoMergeManual() {
		// TODO Auto-generated method stub
		return super.getResultadoMergeManual();
	}
	
	public void setExecutarMergeManual() {
		// TODO Auto-generated method stub
	}
	
	private void setStAx() throws FileNotFoundException, XMLStreamException{
		// Use the reference implementation for the XML input factory
		System.setProperty("javax.xml.stream.XMLInputFactory","com.bea.xml.stream.MXParserFactory");
		// Create the XML input factory
		XMLInputFactory factory= XMLInputFactory.newInstance();
		// Create XML event reader 1
		XMLEventReader r1= factory.createXMLEventReader(new FileReader(getCaminhoArquivoBase()));
		// Create XML event reader 2
		XMLEventReader r2= factory.createXMLEventReader(new FileReader(getCaminhoArquivoDerivado()));
		// Create the output factory
		XMLOutputFactory xmlof= XMLOutputFactory.newInstance();
		// Create XML event writer
		//XMLEventWriter xmlw= xmlof.createXMLEventWriter(System.out);
		XMLEventWriter xmlw= xmlof.createXMLEventWriter(System.out);
		// Read to first <product> element in document 1
		// and output to result document
		String pid1= readToNextElement(r1,xmlw,false);
		// Read to first <product> element in document 1
		// without writing to result document
		String pid2= readToNextElement(r2,null,false);
		// Loop over both XML input streams
		while(pid1 != null || pid2 != null){
			// Compare merge criteria
			if(pid2 == null || (pid1 != null && pid1.compareTo(pid2) <= 0))
				// Continue in document 1
				pid1= readToNextElement(r1,xmlw,pid2 == null);
			else
			// Continue in document 2
			pid2= readToNextElement(r2,xmlw,pid1 == null);
		}
		xmlw.close();
	}
	
	/**
	 * @param reader
	 *            - the document reader
	 * @param writer
	 *            - the document writer
	 * @param processEnd
	 *            � forces the document end to be written
	 * @return - the next merge criterion value
	 * @throws XMLStreamException
	 */
	private static String readToNextElement(XMLEventReader reader, XMLEventWriter writer, boolean processEnd) throws XMLStreamException {
		// Nesting level
		int level= 0;
		while(true){
			// Read event to be written to result document
			XMLEvent event= (XMLEvent) reader.next();
			// Avoid double processing of document end
			if(!processEnd) switch(event.getEventType()){
				case XMLEvent.START_ELEMENT:
					++level;
					break;
				case XMLEvent.END_ELEMENT:
					if(--level < 0) return null;
					break;
			}
			// Output event
			if(writer != null) writer.add(event);
			// Look at next event
			event= reader.peek();
			textoTextPane = textoTextPane + event.toString();
			
			switch(event.getEventType()){
				case XMLEvent.START_ELEMENT:
					// Start element - stop at <product> element
					QName name= event.asStartElement().getName();
					if(name.equals(prodName)){
						return event.asStartElement().getAttributeByName(pidName).getValue();
					}
					break;
				case XMLEvent.END_DOCUMENT:
					// Stop at end of document
					return null;
			}
		}
	}
}
